﻿using JWT;
using JWT.Algorithms;
using JWT.Builder;
using JWT.Exceptions;
using JWT.Serializers;
using Microsoft.AspNetCore.Http;
using System;
using System.Security.Principal;

namespace Microsoft.AspNetCore
{
    public class JwtHelper
    {
        private static string secret = "U3VueXVuLkxvZ0Rhc2hib2FyZC5VSQ==";
        public static string CreateJwt(string account)
        {
            var token = new JwtBuilder()
              .WithAlgorithm(new HMACSHA256Algorithm())
              .WithSecret(secret)
              .AddClaim("exp", DateTimeOffset.UtcNow.AddDays(7).ToUnixTimeSeconds())
              .AddClaim("Account", account)
              .Encode();
            return token;
        }
        public static ProfilePrincipal ParsingJwt(string token)
        {
            ProfilePrincipal profile = null;
            try
            {
                IJsonSerializer serializer = new JsonNetSerializer();
                IDateTimeProvider provider = new UtcDateTimeProvider();
                IJwtValidator validator = new JwtValidator(serializer, provider);
                IBase64UrlEncoder urlEncoder = new JwtBase64UrlEncoder();
                IJwtDecoder decoder = new JwtDecoder(serializer, validator, urlEncoder, new HMACSHA256Algorithm());
                profile = decoder.DecodeToObject<ProfilePrincipal>(token, secret, verify: true);
            }
            catch (TokenExpiredException)
            {
                Console.WriteLine("Token has expired");
            }
            catch (SignatureVerificationException)
            {
                Console.WriteLine("Token has invalid signature");
            }
            catch
            {
            }
            return profile;
        }

        public static IPrincipal GetPrincipal(string token)
        {
            try
            {
                IJsonSerializer serializer = new JsonNetSerializer();
                IDateTimeProvider provider = new UtcDateTimeProvider();
                IJwtValidator validator = new JwtValidator(serializer, provider);
                IBase64UrlEncoder urlEncoder = new JwtBase64UrlEncoder();
                IJwtDecoder decoder = new JwtDecoder(serializer, validator, urlEncoder, new HMACSHA256Algorithm());
                var profile = decoder.DecodeToObject<ProfilePrincipal>(token, secret, verify: true);
                profile.Identity = new ProfileIdentifier(profile.Account, "AnnoLog", true);
                return profile;
            }
            catch
            {
                return null;
            }
        }

        public static void SetSecret(string secret)
        {
            JwtHelper.secret = secret;
        }
        public static string GetSecret()
        {
            return secret;
        }
    }

    public class ProfilePrincipal : IPrincipal
    {
        public ProfilePrincipal() { }
        public ProfilePrincipal(IIdentity identity)
        {
            this.Identity = identity;
        }
        public string Exp { get; set; }
        public string Account { get; set; }

        public IIdentity Identity { get; set; }
        public bool IsInRole(string role) { return false; }
    }

    public class ProfileIdentifier : IIdentity
    {
        public ProfileIdentifier() { }
        public ProfileIdentifier(string name, string authenticationType, bool isAuthenticated)
        {
            this.Name = name;
            this.AuthenticationType = authenticationType;
            this.IsAuthenticated = isAuthenticated;
        }
        public string Name { get; private set; }

        public string AuthenticationType { get; private set; }

        public bool IsAuthenticated { get; private set; }
    }
}
